package com.husky.easyexcle.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.husky.easyexcle.entity.ReadExcelComplexHeadEntity;
import com.husky.easyexcle.entity.ReadExcelIndexOrNameEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @Author husky
 * @Date 2023/2/17 9:42
 * @Description: 复杂表头  读取 Excel 监听器
 **/
@Slf4j
public class ReadExcelComplexHeadListener extends AnalysisEventListener<ReadExcelComplexHeadEntity> {

    /**
     * 每隔51条存储数据库，实际使用中可以100条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 51;

    /**
     * 消费没有返回值的函数式接口
     */
    private final Consumer<List<ReadExcelComplexHeadEntity>> consumer;

    public ReadExcelComplexHeadListener(Consumer<List<ReadExcelComplexHeadEntity>> consumer) {
        this.consumer = consumer;
    }

    /**
     * 缓存的数据
     */
    private List<ReadExcelComplexHeadEntity> dataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    /**
     * 获取复杂表头数据
     * @param headMap 复杂表头数据
     * @param analysisContext 获取Excel上下文对象
     */
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext analysisContext) {
        log.info("获取复杂表头数据={}", JSON.toJSONString(headMap));
    }

    /**
     * 这个每一条数据解析都会来调用
     * @param readExcelComplexHeadEntity 复杂表头 读取 Excel 对应实体类
     * @param analysisContext 获取Excel上下文对象
     */
    @Override
    public void invoke(ReadExcelComplexHeadEntity readExcelComplexHeadEntity, AnalysisContext analysisContext) {
        // log.info("解析数据={}", JSON.toJSONString(readExcelIndexOrNameEntity));

        // 放入结果集
        dataList.add(readExcelComplexHeadEntity);

        //  不超过咱们期望的数据集大小
        if(dataList.size() >= BATCH_COUNT){
            consumer.accept(dataList);
            dataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 数据解析完成调用
     * @param analysisContext 获取Excel上下文对象
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if(CollectionUtils.isNotEmpty(dataList)){
            consumer.accept(dataList);
        }
    }
}
